package com.zbkj.admin.aspect;

import com.zbkj.common.utils.IPUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;


/**
 * +----------------------------------------------------------------------
 * | CRMEB [ CRMEB赋能开发者，助力企业发展 ]
 * +----------------------------------------------------------------------
 * | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed CRMEB并不是自由软件，未经许可不能去掉CRMEB相关版权
 * +----------------------------------------------------------------------
 * | Author: CRMEB Team <admin@crmeb.com>
 * +----------------------------------------------------------------------
 * 所有的前端controller层的拦截业务，方法的执行时间长度，
 */
@Slf4j
@Aspect
@Component
public class ControllerAspect {

    Logger logger = LoggerFactory.getLogger(ControllerAspect.class);

    @Pointcut("(execution(public * com.zbkj.admin.controller..*.*(..)))")
    private void pointCutMethodController() {

    }

    @Before("pointCutMethodController()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            log.info("Remote host:{},Remote port:{},URI:{}", IPUtil.getRemoteHost(request), request.getRemotePort(),
                request.getRequestURI());
            //log.info("Method={}",request.getMethod());
            //log.info("Controller={}",joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());
            for (int i = 0; i < joinPoint.getArgs().length; i++) {
                log.info("Parameter:" + (i + 1) + "=:" + joinPoint.getArgs()[i]);
            }
        }
    }


    @Around("pointCutMethodController()")
    public Object doAroundService(ProceedingJoinPoint pjp) throws Throwable {

        long begin = System.nanoTime();

        Object obj = pjp.proceed();

        long end = System.nanoTime();

        logger.info("Controller method：{}，prams：{}，cost time：{} ns，cost：{} ms",

                pjp.getSignature().toString(), Arrays.toString(pjp.getArgs()), (end - begin), (end - begin) / 1000000);

        return obj;
    }


    @AfterReturning(pointcut = "pointCutMethodController()", returning = "object")
    public void doAfterReturing(Object object) {
        if (object != null) {
            log.info("response={}", object.toString());
        }
    }
}
